<template>
  <div
    size="small"
    :class="['search-group', { isFirstLayer }, { 'show-err': !!errmsg }]"
    :errmsg="errmsg"
  >
    <div class="search-title">
      满足下列
      <el-select
        class="search-select"
        v-model="value.condition"
        style="margin: 0 4px"
        :disabled="disabled"
      >
        <el-option
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      条件：
    </div>

    <div class="search-wrap">
      <item-wrap
        v-for="(item, index) in value.queryFields"
        :key="item.t"
        :hiddenDelete="disabled"
        @remove="removeItem(index)"
      >
        <search-item
          ref="searchItem"
          v-if="!item.queryFields"
          :value="value.queryFields[index]"
          @update-value="updateValue"
          :disabled="disabled"
          :index="index"
        />
        <component
          :is="componentName"
          v-else
          :value="value.queryFields[index]"
          :disabled="disabled"
          @update-value="updateValue"
          ref="searchGroup"
          :isFirstLayer="false"
        />
      </item-wrap>

      <item-wrap v-if="!disabled" :hiddenDelete="true" class="add-condition">
        <el-button plain :icon="Plus" @click="addItem"> 添加单个条件 </el-button>
        <el-button v-if="isFirstLayer" plain :icon="Plus" @click="addGroup">
          添加组合条件
        </el-button>
      </item-wrap>
    </div>
  </div>
</template>
<script setup lang="ts">
import SearchItem from './SearchItem/index.vue'
import { Plus } from '@element-plus/icons-vue'
import ItemWrap from './ItemWrap.vue'
const searchItem = ref(null)
const searchGroup = ref(null)
const componentName = ref('SearchGroup')
defineOptions({
  name: 'SearchGroup'
})
const props = defineProps({
  value: {
    type: Object
  },
  isFirstLayer: {
    type: Boolean,
    default: true
  },
  disabled: Boolean
})

const { isFirstLayer, disabled } = toRefs(props)
const value = ref(props.value)
const options = [
  { value: 'must', label: '全部' },
  { value: 'should', label: '任一' }
]
const errmsg = ref('')

const emit = defineEmits(['updateValue'])

watch(
  () => value,
  (val) => {
    emit('updateValue', val.value)
  },
  {
    deep: true
  }
)
const updateValue = (val, index) => {
  if (index != undefined) value.value.queryFields[index] = val
}
const addItem = () => {
  if (!value.value.queryFields) value.value.queryFields = []
  value.value.queryFields.push({
    field: '',
    value: '',
    queryType: '',
    t: +new Date()
  })
}

const addGroup = () => {
  if (!value.value.queryFields) value.value.queryFields = []
  value.value.queryFields.push({
    condition: '',
    queryFields: [],
    t: +new Date()
  })
}

const removeItem = (i) => {
  value.value.queryFields.splice(i, 1)
}
const setInitValue = (val) => {
  value.value = val
}
const validate = () => {
  return new Promise(async (resolve, reject) => {
    const items = searchItem.value || []
    const groups = searchGroup.value || []
    const rule = Object.keys(value.value).length == 0
    const rules = value.value?.queryFields?.length == 0
    if (rules || rule) {
      errmsg.value = '请补全查询条件'
      reject('表单查询条件不完整')
    } else {
      errmsg.value = ''
    }

    for (const item of groups) {
      try {
        await item.validate()
      } catch (error) {
        reject(error)
      }
    }

    for (const item of items) {
      try {
        await item.validateField({ errmsg: '请补全查询条件' })
      } catch (error) {
        reject(error)
      }
    }
    resolve()
  })
}
defineExpose({ validate, setInitValue })
</script>

<style lang="scss" scoped>
.el-select {
  font-family: 'HarmonyOS_Regular';
  font-size: 12px;
}
.search-group {
  --line-spacing: 16px;
  --line-height: 32px;
  --border-width: 1px;
  line-height: var(--line-height);
  font-size: 13px;
  position: relative;

  :deep(.el-input__inner) {
    min-height: var(--line-height) !important;
  }

  &.isFirstLayer {
    margin-top: var(--line-spacing);
    margin-bottom: var(--line-spacing);
  }

  &.show-err {
    transition: margin-bottom 0.1s;
    margin-bottom: 16px;

    &.isFirstLayer {
      margin-bottom: 24px;
    }

    &::after {
      content: attr(errmsg);
      color: #f56c6c;
      position: absolute;
      left: 0;
      bottom: -18px;
      font-size: 12px;
      line-height: 16px;
    }
  }
}
:deep .search-title {
  font-size: 13px;
  .search-select {
    .el-input {
      .el-input__inner {
        font-size: 12px;
      }
    }
  }
}
.search-wrap {
  padding-top: var(--line-spacing);
  margin-left: 24px;
  border-left: var(--border-width) solid #ededed;
  .add-condition {
    .el-button {
      font-family: 'HarmonyOS_Regular';
      font-size: 12px;
    }
  }
  .item-wrap:last-child {
    position: relative;
    margin-bottom: 0;

    &::before {
      content: '';
      position: absolute;
      right: 100%;
      top: calc(50% + var(--border-width) / 2);
      height: 50%;
      width: var(--border-width);
      background-color: #fff;
    }
  }
}

.item-wrap {
  margin-bottom: var(--line-spacing);
}
</style>
